//
//  PHDeviceManager.m
//  PhnixHome
//
//  Created by Levy Xu on 2018/1/4.
//  Copyright © 2018年 Levy Xu. All rights reserved.
//

#import "PHDeviceManager.h"

#define kLoopInterval 60.0f

NSString *const kDeviceCountChangedNotification = @"kDeviceCountChangedNotification";
NSString *const kDeviceStatusChangedNotification = @"kDeviceStatusChangedNotification";

@interface PHDeviceManager ()
@property(nonatomic, strong) KKTimer *timer;
@property(nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager;
@property(nonatomic, assign) BOOL started;
@end

@implementation PHDeviceManager

SingletonM(PHDeviceManager, [self initMethod];)

-(void)initMethod {
    _deviceList = [NSMutableArray array];
    _reachabilityManager = [AFNetworkReachabilityManager sharedManager];
}

-(void)initThread {
    _userPath = [DOC_DIR stringByAppendingFormat:@"/devices/%@", APP_DELEGATE.token.user_id];
    [FM createDirectoryAtPath:_userPath withIntermediateDirectories:YES attributes:nil error:nil];
    
    NSArray *deviceFiles = [FM contentsOfDirectoryAtPath:_userPath error:nil];
    for (NSString *deviceFile in deviceFiles) {
        NSString *devicePath = [_userPath stringByAppendingPathComponent:deviceFile];
        PHDevice *dev = [PHDevice mj_objectWithFile:devicePath];
        [_deviceList addObject:dev];
    }
    LOG(@"_deviceList %@", _deviceList);
    
    WS(ws);
    [_reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        LOG(@"network chagned %ld", (long)status);
        ws.started = ws.reachabilityManager.isReachable;
    }];
    [_reachabilityManager startMonitoring];
}

-(void)destory {
    [_reachabilityManager stopMonitoring];
    
    self.started = NO;
    
    [_deviceList removeAllObjects];

    _userPath = nil;
}

-(void)setStarted:(BOOL)started {
    if (_started == started) {
        return;
    }
    _started = started;
    if (started) {
        WS(ws);
        _timer = [KKTimer every:kLoopInterval task:^(NSUInteger times) {
            LOG(@"getBoundDevices times %zi", times);
            [ws getBoundDevices:nil];
        }];
        [_timer fire];
        
        for (PHDevice *model in _deviceList) {
            [model startTimer];
        }
    } else {
        for (PHDevice *model in _deviceList) {
            [model stopTimer];
        }
        
        if (_timer && _timer.isValid) {
            [_timer invalidate];
            _timer = nil;
        }
    }
}

-(void)getBoundDevices:(FinishBlock)finish {
    WS(ws);
    [[NetUtils JSONManager] GET:@"device/deviceList.json" parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        CommonResult *result = [CommonResult mj_objectWithKeyValues:[responseObject mj_JSONObject]];
        if (result.is_result_suc) {
            NSArray *list = [PHDevice mj_objectArrayWithKeyValuesArray:result.object_result];
            [ws handleList:list];
            !finish ?: finish(YES);
        } else {
            !finish ?: finish(NO);
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        LOG(@"error %@",error.description);
        !finish ?: finish(NO);
    }];
}

-(void)handleList:(NSArray *)list {
    NSMutableArray *list_copy = [list mutableCopy];
    for (PHDevice *tmp in _deviceList) {
        BOOL exist = NO;
        for (PHDevice *device in list) {
            if ([tmp equalTo:device]) {
                exist = YES;
                BOOL changed = NO;
                if (![tmp.device_name isEqualToString:device.device_name]) {
                    tmp.device_name = device.device_name;
                    changed = YES;
                }
                if (![tmp.device_nick_name isEqualToString:device.device_nick_name]) {
                    tmp.device_nick_name = device.device_nick_name;
                    changed = YES;
                }
                if (![tmp.is_online isEqualToString:device.is_online]) {
                    tmp.is_online = device.is_online;
                    changed = YES;
                }
                if (changed) {//update
                    LOG(@"有更新 %@", tmp.mj_keyValues);
                    NSString *devicePath = [_userPath stringByAppendingPathComponent:tmp.device_code];
                    [tmp.mj_keyValues writeToFile:devicePath atomically:YES];
                    [NNCDC postNotificationName:kDeviceStatusChangedNotification object:tmp];
                }
                [list_copy removeObject:device];
                break;
            }
        }
        if (!exist) {
            if (![tmp.is_online isEqualToString:@"UNBOUND"]) {
                tmp.is_online = @"UNBOUND";
                NSString *devicePath = [_userPath stringByAppendingPathComponent:tmp.device_code];
                [tmp.mj_keyValues writeToFile:devicePath atomically:YES];
                [NNCDC postNotificationName:kDeviceStatusChangedNotification object:tmp];
            }
        }
    }
    for (PHDevice *device in list_copy) {
        [self saveDevice:device];
    }
}

-(BOOL)deviceExist:(PHDevice *)device {
    for (PHDevice *tmp in _deviceList) {
        if ([tmp equalTo:device]) {
            return YES;
        }
    }
    return NO;
}

#pragma mark - 保存和删除
-(void)saveDevice:(PHDevice *)device {
    NSString *devicePath = [_userPath stringByAppendingPathComponent:device.device_code];
    BOOL result = [device.mj_keyValues writeToFile:devicePath atomically:YES];
    if (result) {
        [device startTimer];
        
        [_deviceList addObject:device];
        [NNCDC postNotificationName:kDeviceCountChangedNotification object:nil];
    } else {
        LOG(@"save %@ failed", device.device_code);
    }
}

-(void)removeDevice:(PHDevice *)device {
    WS(ws);
    [device unbind:^(BOOL success) {
        if (success) {
            NSString *devicePath = [ws.userPath stringByAppendingPathComponent:device.device_code];
            BOOL result = [FM removeItemAtPath:devicePath error:nil];
            if (result) {
                [device stopTimer];
                
                [ws.deviceList removeObject:device];
                [NNCDC postNotificationName:kDeviceCountChangedNotification object:nil];
            } else {
                LOG(@"remove %@ failed", device.device_code);
            }
        } else {
            [KKHUD showError:@"删除失败"];
        }
    }];
}
@end
